<!DOCTYPE html>
<html lang="en-us">
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
<meta charset="UTF-8">
<title>Nested Aggregations | Elasticsearch: The Definitive Guide [2.x] | Elastic</title>
<link rel="home" href="index.html" title="Elasticsearch: The Definitive Guide [2.x]">
<link rel="up" href="nested-objects.html" title="Nested Objects">
<link rel="prev" href="nested-sorting.html" title="Sorting by Nested Fields">
<link rel="next" href="parent-child.html" title="Parent-Child Relationship">
<meta name="DC.type" content="Learn/Docs/Legacy/Elasticsearch/Definitive Guide/2.x">
<meta name="DC.subject" content="Elasticsearch">
<meta name="DC.identifier" content="2.x">
<meta name="robots" content="noindex,nofollow">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.optimizely.com/js/18132920325.js"></script>
    <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
    <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
    <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
    <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
    <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
    <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
    <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
    <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
    <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
    <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
    <link rel="manifest" href="/manifest.json">
    <meta name="apple-mobile-web-app-title" content="Elastic">
    <meta name="application-name" content="Elastic">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="/mstile-144x144.png">
    <meta name="theme-color" content="#ffffff">
    <meta name="naver-site-verification" content="936882c1853b701b3cef3721758d80535413dbfd">
    <meta name="yandex-verification" content="d8a47e95d0972434">
    <meta name="localized" content="true">
    <meta name="st:robots" content="follow,index">
    <meta property="og:image" content="https://www.elastic.co/static/images/elastic-logo-200.png">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" href="/favicon.ico" type="image/x-icon">
    <link rel="apple-touch-icon-precomposed" sizes="64x64" href="/favicon_64x64_16bit.png">
    <link rel="apple-touch-icon-precomposed" sizes="32x32" href="/favicon_32x32.png">
    <link rel="apple-touch-icon-precomposed" sizes="16x16" href="/favicon_16x16.png">
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="/guide/static/styles.css">
  </head>

  <!--© 2015-2021 Elasticsearch B.V. Copying, publishing and/or distributing without written permission is strictly prohibited.-->

  <body>
    <!-- Google Tag Manager -->
    <script>dataLayer = [];</script><noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-58RLH5" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-58RLH5');</script>
    <!-- End Google Tag Manager -->

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-12395217-16"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'UA-12395217-16');
    </script>

    <!--BEGIN QUALTRICS WEBSITE FEEDBACK SNIPPET-->
    <script type="text/javascript">
      (function(){var g=function(e,h,f,g){
      this.get=function(a){for(var a=a+"=",c=document.cookie.split(";"),b=0,e=c.length;b<e;b++){for(var d=c[b];" "==d.charAt(0);)d=d.substring(1,d.length);if(0==d.indexOf(a))return d.substring(a.length,d.length)}return null};
      this.set=function(a,c){var b="",b=new Date;b.setTime(b.getTime()+6048E5);b="; expires="+b.toGMTString();document.cookie=a+"="+c+b+"; path=/; "};
      this.check=function(){var a=this.get(f);if(a)a=a.split(":");else if(100!=e)"v"==h&&(e=Math.random()>=e/100?0:100),a=[h,e,0],this.set(f,a.join(":"));else return!0;var c=a[1];if(100==c)return!0;switch(a[0]){case "v":return!1;case "r":return c=a[2]%Math.floor(100/c),a[2]++,this.set(f,a.join(":")),!c}return!0};
      this.go=function(){if(this.check()){var a=document.createElement("script");a.type="text/javascript";a.src=g;document.body&&document.body.appendChild(a)}};
      this.start=function(){var a=this;window.addEventListener?window.addEventListener("load",function(){a.go()},!1):window.attachEvent&&window.attachEvent("onload",function(){a.go()})}};
      try{(new g(100,"r","QSI_S_ZN_emkP0oSe9Qrn7kF","https://znemkp0ose9qrn7kf-elastic.siteintercept.qualtrics.com/WRSiteInterceptEngine/?Q_ZID=ZN_emkP0oSe9Qrn7kF")).start()}catch(i){}})();
    </script><div id="ZN_emkP0oSe9Qrn7kF"><!--DO NOT REMOVE-CONTENTS PLACED HERE--></div>
    <!--END WEBSITE FEEDBACK SNIPPET-->

    <div id="elastic-nav" style="display:none;"></div>
    <script src="https://www.elastic.co/elastic-nav.js"></script>

    <!-- Subnav -->
    <div>
      <div>
        <div class="tertiary-nav d-none d-md-block">
          <div class="container">
            <div class="p-t-b-15 d-flex justify-content-between nav-container">
              <div class="breadcrum-wrapper"><span><a href="/guide/" style="font-size: 14px; font-weight: 600; color: #000;">Docs</a></span></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="main-container">
      <section id="content">
        <div class="content-wrapper">

          <section id="guide" lang="en">
            <div class="container">
              <div class="row">
                <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                  <!-- start body -->
                  <div class="page_header">
<p>
  <strong>WARNING</strong>: The 2.x versions of Elasticsearch have passed their
  <a href="https://www.elastic.co/support/eol">EOL dates</a>. If you are running
  a 2.x version, we strongly advise you to upgrade.
</p>
<p>
  This documentation is no longer maintained and may be removed. For the latest
  information, see the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">current
  Elasticsearch documentation</a>.
</p>
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: The Definitive Guide [2.x]</a></span>
»
<span class="breadcrumb-link"><a href="modeling-your-data.html">Modeling Your Data</a></span>
»
<span class="breadcrumb-link"><a href="nested-objects.html">Nested Objects</a></span>
»
<span class="breadcrumb-node">Nested Aggregations</span>
</div>
<div class="navheader">
<span class="prev">
<a href="nested-sorting.html">« Sorting by Nested Fields</a>
</span>
<span class="next">
<a href="parent-child.html">Parent-Child Relationship »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="nested-aggregation"></a>Nested Aggregations<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/402_Nested/35_Nested_aggs.asciidoc">edit</a>
</h2>
</div></div></div>
<p>In the same way as we need to use the special <code class="literal">nested</code> query to gain access to
nested objects at search time, the dedicated <code class="literal">nested</code> aggregation allows us to
aggregate fields in nested objects:</p>
<div class="pre_wrapper lang-json">
<pre class="programlisting prettyprint lang-json">GET /my_index/blogpost/_search
{
  "size" : 0,
  "aggs": {
    "comments": { <a id="CO275-1"></a><i class="conum" data-value="1"></i>
      "nested": {
        "path": "comments"
      },
      "aggs": {
        "by_month": {
          "date_histogram": { <a id="CO275-2"></a><i class="conum" data-value="2"></i>
            "field":    "comments.date",
            "interval": "month",
            "format":   "yyyy-MM"
          },
          "aggs": {
            "avg_stars": {
              "avg": { <a id="CO275-3"></a><i class="conum" data-value="3"></i>
                "field": "comments.stars"
              }
            }
          }
        }
      }
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO275-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">nested</code> aggregation “steps down” into the nested <code class="literal">comments</code> object.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO275-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>Comments are bucketed into months based on the <code class="literal">comments.date</code> field.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO275-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>The average number of stars is calculated for each bucket.</p>
</td>
</tr>
</table>
</div>
<p>The results show that aggregation has happened at the nested document level:</p>
<div class="pre_wrapper lang-json">
<pre class="programlisting prettyprint lang-json">...
"aggregations": {
  "comments": {
     "doc_count": 4, <a id="CO276-1"></a><i class="conum" data-value="1"></i>
     "by_month": {
        "buckets": [
           {
              "key_as_string": "2014-09",
              "key": 1409529600000,
              "doc_count": 1, <a id="CO276-2"></a><i class="conum" data-value="1"></i>
              "avg_stars": {
                 "value": 4
              }
           },
           {
              "key_as_string": "2014-10",
              "key": 1412121600000,
              "doc_count": 3, <a id="CO276-3"></a><i class="conum" data-value="1"></i>
              "avg_stars": {
                 "value": 2.6666666666666665
              }
           }
        ]
     }
  }
}
...</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO276-1"><i class="conum" data-value="1"></i></a><a href="#CO276-2"></a><a href="#CO276-3"></a></p>
</td>
<td align="left" valign="top">
<p>There are a total of four <code class="literal">comments</code>: one in September and three in October.</p>
</td>
</tr>
</table>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="reverse-nested-aggregation"></a>reverse_nested Aggregation<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/402_Nested/35_Nested_aggs.asciidoc">edit</a>
</h3>
</div></div></div>
<p>A <code class="literal">nested</code> aggregation can access only the fields within the nested document.
It can’t see fields in the root document or in a different nested document.
However, we can <em>step out</em> of the nested scope back into the parent with a
<code class="literal">reverse_nested</code> aggregation.</p>
<p>For instance, we can find out which <code class="literal">tags</code> our commenters are interested in,
based on the age of the commenter.  The <code class="literal">comment.age</code> is a nested field, while
the <code class="literal">tags</code> are in the root document:</p>
<div class="pre_wrapper lang-json">
<pre class="programlisting prettyprint lang-json">GET /my_index/blogpost/_search
{
  "size" : 0,
  "aggs": {
    "comments": {
      "nested": { <a id="CO277-1"></a><i class="conum" data-value="1"></i>
        "path": "comments"
      },
      "aggs": {
        "age_group": {
          "histogram": { <a id="CO277-2"></a><i class="conum" data-value="2"></i>
            "field":    "comments.age",
            "interval": 10
          },
          "aggs": {
            "blogposts": {
              "reverse_nested": {}, <a id="CO277-3"></a><i class="conum" data-value="3"></i>
              "aggs": {
                "tags": {
                  "terms": { <a id="CO277-4"></a><i class="conum" data-value="4"></i>
                    "field": "tags"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO277-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">nested</code> agg steps down into the <code class="literal">comments</code> object.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO277-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">histogram</code> agg groups on the <code class="literal">comments.age</code> field, in buckets
of 10 years.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO277-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">reverse_nested</code> agg steps back up to the root document.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO277-4"><i class="conum" data-value="4"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">terms</code> agg counts popular terms per age group of the commenter.</p>
</td>
</tr>
</table>
</div>
<p>The abbreviated results show us the following:</p>
<div class="pre_wrapper lang-json">
<pre class="programlisting prettyprint lang-json">..
"aggregations": {
  "comments": {
     "doc_count": 4, <a id="CO278-1"></a><i class="conum" data-value="1"></i>
     "age_group": {
        "buckets": [
           {
              "key": 20, <a id="CO278-2"></a><i class="conum" data-value="2"></i>
              "doc_count": 2, <a id="CO278-3"></a><i class="conum" data-value="2"></i>
              "blogposts": {
                 "doc_count": 2, <a id="CO278-4"></a><i class="conum" data-value="3"></i>
                 "tags": {
                    "doc_count_error_upper_bound": 0,
                    "buckets": [ <a id="CO278-5"></a><i class="conum" data-value="4"></i>
                       { "key": "shares",   "doc_count": 2 },
                       { "key": "cash",     "doc_count": 1 },
                       { "key": "equities", "doc_count": 1 }
                    ]
                 }
              }
           },
...</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO278-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>There are four comments.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO278-2"><i class="conum" data-value="2"></i></a><a href="#CO278-3"></a></p>
</td>
<td align="left" valign="top">
<p>There are two comments by commenters between the ages of 20 and 30.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO278-4"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>Two blog posts are associated with those comments.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO278-5"><i class="conum" data-value="4"></i></a></p>
</td>
<td align="left" valign="top">
<p>The popular tags in those blog posts are <code class="literal">shares</code>, <code class="literal">cash</code>, and <code class="literal">equities</code>.</p>
</td>
</tr>
</table>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_when_to_use_nested_objects"></a>When to Use Nested Objects<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/402_Nested/35_Nested_aggs.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Nested objects are useful when there is one main entity, like our <code class="literal">blogpost</code>,
with a limited number of closely related but less important entities, such as
comments.  It is useful to be able to find blog posts based on the content of
the comments, and the <code class="literal">nested</code> query and filter provide for fast query-time
joins.</p>
<p>The disadvantages of the nested model are as follows:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
To add, change, or delete  a nested document, the whole document must be
reindexed. This becomes more costly the more nested documents there are.
</li>
<li class="listitem">
Search requests return the whole document, not just the matching nested
 documents. Although there are plans afoot to support returning the best
-matching nested documents with the root document, this is not yet supported.
</li>
</ul>
</div>
<p>Sometimes you need a complete separation between the main document and its
associated entities.  This separation is provided by the <em>parent-child
relationship</em>.</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="nested-sorting.html">« Sorting by Nested Fields</a>
</span>
<span class="next">
<a href="parent-child.html">Parent-Child Relationship »</a>
</span>
</div>
</div>

                  <!-- end body -->
                </div>
                <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                  <div id="rtpcontainer" style="display: block;">
                    <div class="mktg-promo">
                      <h3>Most Popular</h3>
                      <ul class="icons">
                        <li class="icon-elasticsearch-white"><a href="https://www.elastic.co/webinars/getting-started-elasticsearch?baymax=default&amp;elektra=docs&amp;storm=top-video">Get Started with Elasticsearch: Video</a></li>
                        <li class="icon-kibana-white"><a href="https://www.elastic.co/webinars/getting-started-kibana?baymax=default&amp;elektra=docs&amp;storm=top-video">Intro to Kibana: Video</a></li>
                        <li class="icon-logstash-white"><a href="https://www.elastic.co/webinars/introduction-elk-stack?baymax=default&amp;elektra=docs&amp;storm=top-video">ELK for Logs &amp; Metrics: Video</a></li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>

        </div>


<div id="elastic-footer"></div>
<script src="https://www.elastic.co/elastic-footer.js"></script>
<!-- Footer Section end-->

      </section>
    </div>

<script src="/guide/static/jquery.js"></script>
<script type="text/javascript" src="/guide/static/docs.js"></script>
<script type="text/javascript">
  window.initial_state = {}</script>
  </body>
</html>
